from aiogram_dialog import DialogManager
from sqlalchemy.ext.asyncio import AsyncSession

from app.bot.services.date_time import get_date_time
from app.bot.services.helpers import get_expiring_on, get_price_by_category
from app.bot.services.locale import Locale
from app.database.enums import ServerPrivacy, ServerType
from app.database.services.allowed_ips import get_allowed_ip_by_order
from app.database.services.categories import (
    get_category,
    get_category_by_name,
    get_category_for_private,
)
from app.database.services.countries import get_country
from app.database.services.orders.common import get_order, get_orders
from app.database.services.orders.subscriptions import get_user_subscription_order
from app.database.services.providers import get_provider
from app.database.services.proxy import get_proxy
from app.database.services.sites import get_site


async def all_orders_getter(
    db_session: AsyncSession, dialog_manager: DialogManager, **kwargs
):
    orders = await get_orders(db_session)

    return {"orders": orders}


async def order_getter(
    db_session: AsyncSession, dialog_manager: DialogManager, **kwargs
):

    locale: Locale = dialog_manager.middleware_data.get("locale")
    user_id: int = dialog_manager.middleware_data["event_from_user"].id
    if dialog_manager.start_data and dialog_manager.start_data.get("order_id"):
        order_id: int = dialog_manager.start_data.get("order_id")
        order = await get_order(db_session, order_id, joined=True)
        dialog_manager.dialog_data["order_id"] = order_id
    else:
        order = await get_user_subscription_order(db_session, user_id)
        order_id: int = order.id
        dialog_manager.dialog_data["order_id"] = order.id
    allowed_ip = await get_allowed_ip_by_order(
        db_session, order.user.telegram_id, order_id
    )

    if order.auto_renew:
        dialog_manager.dialog().find("autorenew").default = True
    else:
        dialog_manager.dialog().find("autorenew").default = False

    category = None
    country = None
    provider = None

    if locale.translators[0].locale == "ru":
        if order.country:
            country = order.country.name
        if order.category:
            category = order.category.name
        if order.provider:
            provider = order.provider.name
    else:
        if order.country:
            country = order.country.name_eng
        if order.category:
            category = order.category.name_eng
        if order.provider:
            provider = order.provider.name_eng

    if order.expiring_on:
        expiring_on = order.expiring_on
    else:
        expiring_on = ""

    site = order.site.name if order.site else None

    server_time = get_date_time()
    status = locale.get(order.status)
    order_period = locale.get(order.period.value)

    data = {
        "order_id": order.id,
        "period": order.period,
        "order_period": order_period,
        "status": status,
        "order_type": order.type,
        "order_status": order.status,
        "proxies_amount": len(order.proxies),
        "package_price": order.summ,
        "complete_price": order.summ_total,
        "created_at": order.was_created,
        "expiring_on": expiring_on,
        "server_time": server_time,
        "country": country,
        "category": category,
        "provider": provider,
        "site": site,
    }

    if order.proxies:
        proxy = await get_proxy(db_session, order.proxies[0].id)
        proxy_type = proxy.server.proxy_type
        proxy_privacy = proxy.server.proxy_privacy
        data.update(
            {
                "proxy_type_translated": locale.get(proxy_type.value),
                "proxy_type": proxy_type.value,
                "proxy_privacy": proxy_privacy.value,
                "proxy_privacy_translated": locale.get(proxy_privacy.value),
                "one_proxy_price": round(order.summ / len(order.proxies), 2),
                "authorization_type": locale.get(proxy.authorization_type),
                "authorization_ip": allowed_ip.ip_address if allowed_ip else None,
            }
        )

        if proxy_type == ServerType.mobile and proxy_privacy == ServerPrivacy.private:
            data.update(
                {
                    "rotation_period": proxy.reload_period,
                    "rotation_type": locale.get(proxy.reload_type),
                }
            )

    return data


async def extend_summary_getter(
    db_session: AsyncSession, dialog_manager: DialogManager, **kwargs
):

    order_id: int = dialog_manager.dialog_data.get("order_id")
    period: str = dialog_manager.dialog_data.get("period")
    order = await get_order(db_session, order_id, joined=True)

    extended_expiring_on = await get_expiring_on(order.expiring_on, period)
    if order.type == "proxy":
        extend_price = await get_price_by_category(
            period, order.category, len(order.proxies)
        )
    else:
        extend_price = order.category.price_1m

    dialog_manager.dialog_data["extend_price"] = extend_price

    return {
        "order_id": order_id,
        "expiring_on": order.expiring_on,
        "extended_expiring_on": extended_expiring_on,
        "extend_price": extend_price,
    }


async def order_summary_getter(
    db_session: AsyncSession, dialog_manager: DialogManager, **kwargs
):
    locale: Locale = dialog_manager.middleware_data.get("locale")

    proxy_type: str = dialog_manager.dialog_data.get("proxy_type")
    proxy_privacy: str = dialog_manager.dialog_data.get("proxy_privacy")

    country_id: int = dialog_manager.dialog_data.get("country_id")
    country = await get_country(db_session, country_id)

    provider_id: int = dialog_manager.dialog_data.get("provider_id")
    provider = await get_provider(db_session, provider_id)

    category_id: int = dialog_manager.dialog_data.get("category_id")

    if category_id:
        category = await get_category(db_session, category_id)
    else:
        category = await get_category_for_private(db_session, country_id, provider_id)

    site_id: int = dialog_manager.dialog_data.get("site_id")

    site = None
    if site_id:
        site = await get_site(db_session, site_id)

    selected_amount: int = dialog_manager.dialog_data.get("selected_amount")
    period: str = dialog_manager.dialog_data.get("period")

    if dialog_manager.start_data and dialog_manager.start_data.get("for_test"):
        order_summ = 0
    else:
        order_summ = await get_price_by_category(period, category, selected_amount)

    period = locale.get(period)
    proxy_type = locale.get(proxy_type)
    proxy_privacy = locale.get(proxy_privacy)

    if locale.translators[0].locale == "ru":
        country = country.name if country else None
        category = category.name
        provider = provider.name if provider else None
    else:
        country = country.name_eng if country else None
        category = category.name_eng
        provider = provider.name_eng if provider else None

    dialog_manager.dialog_data["order_summ"] = order_summ

    return {
        "proxy_type": proxy_type,
        "proxy_privacy": proxy_privacy,
        "country": country,
        "provider": provider,
        "category": category,
        "site": site,
        "selected_amount": selected_amount,
        "period": period,
        "order_summ": order_summ,
    }


async def subscription_summary_getter(
    db_session: AsyncSession, dialog_manager: DialogManager, **kwargs
):
    locale: Locale = dialog_manager.middleware_data.get("locale")
    category = await get_category_by_name(db_session, "Подписка")
    period: str = dialog_manager.dialog_data.get("subscription_period")

    subscription_summ = await get_price_by_category(period, category, 1)
    dialog_manager.dialog_data["subscription_summ"] = subscription_summ

    return {
        "subscription_summ": subscription_summ,
        "period": locale.get(period),
    }


async def vpn_summary_getter(
    db_session: AsyncSession, dialog_manager: DialogManager, **kwargs
):
    locale: Locale = dialog_manager.middleware_data.get("locale")
    category = await get_category_by_name(db_session, "VPN")
    period = "one_month"

    vpn_summ = await get_price_by_category(period, category, 1)
    dialog_manager.dialog_data["vpn_summ"] = vpn_summ

    return {
        "vpn_summ": vpn_summ,
        "period": locale.get(period),
        "service_name": locale.get("vpn-service")
    }


async def vpn_router_summary_getter(
    db_session: AsyncSession, dialog_manager: DialogManager, **kwargs
):
    locale: Locale = dialog_manager.middleware_data.get("locale")
    category = await get_category_by_name(db_session, "VPN Router")

    vpn_summ = await get_price_by_category("one_month", category, 1)
    dialog_manager.dialog_data["vpn_summ"] = vpn_summ

    return {
        "vpn_summ": vpn_summ,
        "service_name": locale.get("vpn-router-service")
    }
